package com.eduagent.xwqeduagent.utils;

import com.qcloud.cos.COSClient;
import com.qcloud.cos.exception.CosClientException;
import com.qcloud.cos.exception.CosServiceException;
import com.qcloud.cos.model.COSObject;
import com.qcloud.cos.model.COSObjectInputStream;
import com.qcloud.cos.model.GetObjectRequest;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.model.PutObjectResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.UUID;

/**
 * 腾讯云对象存储工具类
 */
@Component
@Slf4j
public class CosUtils {

    @Autowired
    private COSClient cosClient;

    @Value("${cos.client.bucket}")
    private String bucket;

    @Value("${cos.client.host}")
    private String host;

    /**
     * 上传文件到腾讯云COS
     *
     * @param file 文件
     * @param directory 目录
     * @return 文件访问URL
     */
    public String uploadFile(MultipartFile file, String directory) {
        try {
            // 生成唯一文件名
            String originalFilename = file.getOriginalFilename();
            String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
            String key = directory + "/" + UUID.randomUUID() + suffix;

            // 设置元数据
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentLength(file.getSize());
            metadata.setContentType(file.getContentType());

            // 上传请求
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, key, file.getInputStream(), metadata);
            PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);
            
            log.info("File uploaded successfully: {}", key);
            return host + "/" + key;
        } catch (CosServiceException e) {
            log.error("COS service error: {}", e.getMessage(), e);
            throw new RuntimeException("文件上传到腾讯云失败: " + e.getMessage(), e);
        } catch (CosClientException e) {
            log.error("COS client error: {}", e.getMessage(), e);
            throw new RuntimeException("文件上传到腾讯云失败: " + e.getMessage(), e);
        } catch (IOException e) {
            log.error("IO error: {}", e.getMessage(), e);
            throw new RuntimeException("文件读取失败: " + e.getMessage(), e);
        }
    }

    /**
     * 上传本地文件到腾讯云COS
     *
     * @param localFile 本地文件
     * @param directory 目录
     * @return 文件访问URL
     */
    public String uploadFile(File localFile, String directory) {
        try {
            // 生成唯一文件名
            String originalFilename = localFile.getName();
            String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
            String key = directory + "/" + UUID.randomUUID() + suffix;

            // 上传请求
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, key, localFile);
            PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);
            
            log.info("File uploaded successfully: {}", key);
            return host + "/" + key;
        } catch (CosServiceException e) {
            log.error("COS service error: {}", e.getMessage(), e);
            throw new RuntimeException("文件上传到腾讯云失败: " + e.getMessage(), e);
        } catch (CosClientException e) {
            log.error("COS client error: {}", e.getMessage(), e);
            throw new RuntimeException("文件上传到腾讯云失败: " + e.getMessage(), e);
        }
    }

    /**
     * 上传输入流到腾讯云COS
     *
     * @param inputStream 输入流
     * @param fileName 文件名
     * @param contentType 内容类型
     * @param directory 目录
     * @param fileSize 文件大小
     * @return 文件访问URL
     */
    public String uploadFile(InputStream inputStream, String fileName, String contentType, String directory, long fileSize) {
        try {
            // 生成唯一文件名
            String suffix = fileName.substring(fileName.lastIndexOf("."));
            String key = directory + "/" + UUID.randomUUID() + suffix;

            // 设置元数据
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentLength(fileSize);
            metadata.setContentType(contentType);

            // 上传请求
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, key, inputStream, metadata);
            PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);
            
            log.info("File uploaded successfully: {}", key);
            return host + "/" + key;
        } catch (CosServiceException e) {
            log.error("COS service error: {}", e.getMessage(), e);
            throw new RuntimeException("文件上传到腾讯云失败: " + e.getMessage(), e);
        } catch (CosClientException e) {
            log.error("COS client error: {}", e.getMessage(), e);
            throw new RuntimeException("文件上传到腾讯云失败: " + e.getMessage(), e);
        }
    }

    /**
     * 删除腾讯云COS上的文件
     *
     * @param fileUrl 文件URL
     * @return 是否删除成功
     */
    public boolean deleteFile(String fileUrl) {
        try {
            // 从URL中提取key
            String key = fileUrl.replace(host + "/", "");
            cosClient.deleteObject(bucket, key);
            log.info("File deleted successfully: {}", key);
            return true;
        } catch (CosServiceException e) {
            log.error("COS service error: {}", e.getMessage(), e);
            return false;
        } catch (CosClientException e) {
            log.error("COS client error: {}", e.getMessage(), e);
            return false;
        }
    }

    /**
     * 根据key删除腾讯云COS上的文件
     *
     * @param key 文件key
     * @return 是否删除成功
     */
    public boolean deleteFileByKey(String key) {
        try {
            cosClient.deleteObject(bucket, key);
            log.info("File deleted successfully: {}", key);
            return true;
        } catch (CosServiceException e) {
            log.error("COS service error: {}", e.getMessage(), e);
            return false;
        } catch (CosClientException e) {
            log.error("COS client error: {}", e.getMessage(), e);
            return false;
        }
    }
    
    /**
     * 检查文件是否存在
     *
     * @param key 文件key
     * @return 是否存在
     */
    public boolean doesObjectExist(String key) {
        try {
            return cosClient.doesObjectExist(bucket, key);
        } catch (CosServiceException e) {
            log.error("COS service error: {}", e.getMessage(), e);
            return false;
        } catch (CosClientException e) {
            log.error("COS client error: {}", e.getMessage(), e);
            return false;
        }
    }
    
    /**
     * 从URL获取文件key
     *
     * @param fileUrl 文件URL
     * @return 文件key
     */
    public String getFileKeyFromUrl(String fileUrl) {
        return fileUrl.replace(host + "/", "");
    }

    /**
     * 从腾讯云COS下载文件到本地
     *
     * @param key COS中的文件key
     * @param localFile 本地文件
     * @return 是否下载成功
     */
    public boolean downloadFile(String key, File localFile) {
        try {
            // 获取文件
            GetObjectRequest getObjectRequest = new GetObjectRequest(bucket, key);
            COSObject cosObject = cosClient.getObject(getObjectRequest);
            COSObjectInputStream cosObjectInput = cosObject.getObjectContent();
            
            // 保存到本地文件
            Files.copy(cosObjectInput, localFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
            cosObjectInput.close();
            
            log.info("File downloaded successfully: {} -> {}", key, localFile.getAbsolutePath());
            return true;
        } catch (CosServiceException e) {
            log.error("COS service error: {}", e.getMessage(), e);
            return false;
        } catch (CosClientException e) {
            log.error("COS client error: {}", e.getMessage(), e);
            return false;
        } catch (IOException e) {
            log.error("IO error: {}", e.getMessage(), e);
            return false;
        }
    }
    
    /**
     * 从腾讯云COS获取文件内容为字符串
     *
     * @param key COS中的文件key
     * @return 文件内容
     */
    public String getFileContentAsString(String key) {
        try {
            // 获取文件
            GetObjectRequest getObjectRequest = new GetObjectRequest(bucket, key);
            COSObject cosObject = cosClient.getObject(getObjectRequest);
            COSObjectInputStream cosObjectInput = cosObject.getObjectContent();
            
            // 读取内容
            byte[] bytes = cosObjectInput.readAllBytes();
            cosObjectInput.close();
            
            return new String(bytes);
        } catch (CosServiceException e) {
            log.error("COS service error: {}", e.getMessage(), e);
            throw new RuntimeException("获取文件内容失败: " + e.getMessage(), e);
        } catch (CosClientException e) {
            log.error("COS client error: {}", e.getMessage(), e);
            throw new RuntimeException("获取文件内容失败: " + e.getMessage(), e);
        } catch (IOException e) {
            log.error("IO error: {}", e.getMessage(), e);
            throw new RuntimeException("读取文件内容失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 从腾讯云COS获取文件输入流
     *
     * @param key COS中的文件key
     * @return 文件输入流
     */
    public InputStream getFileInputStream(String key) {
        try {
            // 获取文件
            GetObjectRequest getObjectRequest = new GetObjectRequest(bucket, key);
            COSObject cosObject = cosClient.getObject(getObjectRequest);
            return cosObject.getObjectContent();
        } catch (CosServiceException e) {
            log.error("COS service error: {}", e.getMessage(), e);
            throw new RuntimeException("获取文件输入流失败: " + e.getMessage(), e);
        } catch (CosClientException e) {
            log.error("COS client error: {}", e.getMessage(), e);
            throw new RuntimeException("获取文件输入流失败: " + e.getMessage(), e);
        }
    }
} 